<?

class fileDriver extends ObjectClass {

	/* ---------------------------------
	 |            PUBLIQUE            |
	 ---------------------------------*/

	function initData () {
		//Aucune data a initialiser pour dossiers et fichiers.
	}

	function file_exists_i($file)
	{
		$r = glob(sql_regcase($file));
		if (empty($r)) return false;
		else return true;
	}

	function getCaseSensitiveName($file)
	{
		$r = glob(sql_regcase($file));
		$r = preg_replace("#^\.\/#","",$r);
		if (empty($r)) return false;
		else return $r[0];
	}

	function Purge() {
		//Aucun champ a purger, car on ne peut pas en creer
	}

	function mk_dir($path, $rights = 0777){
		$folder_path = array($path);
		while(!@is_dir(dirname(end($folder_path)))
		&& dirname(end($folder_path)) != '/'
		&& dirname(end($folder_path)) != '.'
		&& dirname(end($folder_path)) != '')
		array_push($folder_path, dirname(end($folder_path)));
		while($parent_folder_path = array_pop($folder_path))
		if(!@mkdir($parent_folder_path, $rights))
		user_error("Can't create folder \"$parent_folder_path\".");
	}

	function LimitSize($OrigAdresse,$Dossier,$Nom,$Largeur,$Hauteur,$Out)
	{
		//On verifie l'existence d'un fichier redimensionne
		//$TabNom = explode(".",$Nom);
		preg_match("#([A-z\/\-0-9\@\*\.]+)\.([A-z]+)$#",$Nom,$out);
		$TabNom[0] = $out[1];
		$TabNom[1] = strtolower($out[2]);
		$Dir = $Dossier;
		if (!file_exists($Dir)) fileDriver::mk_dir($Dir);
		//$RenamedOAdr = str_replace("/","_",$Dossier);
		//$Name = "/".$TabNom[0].".mini.".$Largeur."x".$Hauteur.$RenamedOAdr.".".$GLOBALS["Systeme"]->type;
		$Name = "/".$Nom.".mini.".$Largeur."x".$Hauteur.".".$TabNom[1];
		if (file_exists($Dir.$Name)) return $Dir.$Name;
		//On verifie l'existence du fichier original
		if (!file_exists($OrigAdresse)) return false;
		//On commence le travail de l'image
		$Dimensions = getimagesize($OrigAdresse);
		//On prend l'image selon le type
		if ($TabNom[1]=="jpg"||$TabNom[1]=="jpeg") $Img = imagecreatefromjpeg($OrigAdresse);
		elseif ($TabNom[1]=="gif") $Img = imagecreatefromgif($OrigAdresse);
		elseif ($TabNom[1]=="png") $Img = imagecreatefrompng($OrigAdresse);
		elseif ($TabNom[1]=="flv") {
			$movie = new ffmpeg_movie($OrigAdresse);
			$Dimensions[1]=$movie->getFrameHeight();
			$Dimensions[0]=$movie->getFrameWidth();
			$Img=$movie->getFrame(100);
			$Img = $Img->toGDImage();
			//echo 'ffmpeg -i "'.$OrigAdresse.'" -vcodec mjpeg -vframes 1 -an -f rawvideo -s "'.$Largeur.'x'.$Hauteur.'" "'.$Dir.$Name.'"';
			//exec('ffmpeg -i "'.$OrigAdresse.'" -vcodec mjpeg -vframes 200 -an -f rawvideo -s "'.$Largeur.'x'.$Hauteur.'" "'.$Dir.$Name.'"');
	        }else return false;
		//On calcule le redimensionnement sans anamorphoser la photo
		if ($Dimensions[1]>$Hauteur || $Dimensions[0]>$Largeur){
			if ($Dimensions[1]<$Dimensions[0]){
				//Cas Paysage
				$Rapport = $Largeur/$Dimensions[0];
				if ($Rapport*$Dimensions[1]>$Hauteur){
					$Rapport = $Hauteur/$Dimensions[1];
				}
			}else{
				//Cas Portrait
				$Rapport = $Hauteur/$Dimensions[1];
				if ($Rapport*$Dimensions[0]>$Largeur){
					$Rapport = $Largeur/$Dimensions[0];
				}
			}
			$Width  = $Dimensions[0] * $Rapport;
			$Height  = $Dimensions[1] * $Rapport;
		}else{
			$Width  = $Dimensions[0];
			$Height  = $Dimensions[1];
		}
		$Caneva = imagecreatetruecolor($Width,$Height);
		imagecopyresampled($Caneva,$Img,0,0,0,0,$Width,$Height,$Dimensions[0],$Dimensions[1]);
		imagedestroy($Img);
		if ($Out=="jpg"||$Out=="jpeg") $Test = imagejpeg($Caneva,$Dir.$Name,100);
		elseif ($Out=="gif") $Test = imagegif($Caneva,$Dir.$Name);
		elseif ($Out=="png") $Test = imagepng($Caneva,$Dir.$Name);
		imagedestroy($Caneva);
		return ($Test) ? $Dir.$Name : false;
	}

	function Miniature($OrigAdresse,$Dossier,$Nom,$Largeur,$Hauteur,$Out){
		//On verifie l'existence d'un fichier redimensionne
		preg_match("#([A-z\/\-0-9\@\*\.]+)\.([A-z]+)$#",$Nom,$out);
		$TabNom[0] = $out[1];
		$TabNom[1] = strtolower($out[2]);
		for ($i=1;$i<count($TabNom)-1;$i++) $TabNom[0] .= $TabNom[$i];
		$TabNom[1] = $TabNom[count($TabNom)-1];
		$Dir = $Dossier;
		if (!file_exists($Dir)) fileDriver::mk_dir($Dir);
		//$RenamedOAdr = str_replace("/","_",$Dossier);
		//$Name = "/".$TabNom[0].".mini.".$Largeur."x".$Hauteur.$RenamedOAdr.".".$GLOBALS["Systeme"]->type;
		$Name = "/".$Nom.".mini.".$Largeur."x".$Hauteur.".".$TabNom[1];
		if (file_exists($Dir.$Name)) return $Dir.$Name;
		//On verifie l'existence du fichier original
		// 		echo $OrigAdresse;
		if (!file_exists($OrigAdresse)) return false;
		//On commence le travail de l'image
		$Dimensions = getimagesize($OrigAdresse);
		//On prend l'image selon le type
		$Caneva = imagecreatetruecolor($Largeur,$Hauteur);
		$TabNom[1] = strtolower($TabNom[1]);
		if ($TabNom[1]=="jpg"||$TabNom[1]=="jpeg") $Img = imagecreatefromjpeg($OrigAdresse);
		elseif ($TabNom[1]=="gif") $Img = imagecreatefromgif($OrigAdresse);
		elseif ($TabNom[1]=="png") $Img = imagecreatefrompng($OrigAdresse);
		elseif ($TabNom[1]=="flv") {
			$movie = new ffmpeg_movie($OrigAdresse);
			$Dimensions[1]=$movie->getFrameHeight();
			$Dimensions[0]=$movie->getFrameWidth();
			$Img=$movie->getFrame(100);
			$Img = $Img->toGDImage();
			//echo "YARGLAA";
		}
		else return false;
		//On calcule le redimensionnement sans anamorphoser la photo
		if ($Dimensions[1]>$Hauteur || $Dimensions[0]>$Largeur){
			if ($Dimensions[1]>$Dimensions[0]){
				//Cas du paysage
				$Height = $Hauteur;
				$Width  = $Dimensions[0] * ($Hauteur/$Dimensions[1]);
				if ($Width<$Largeur)
				{
					$Width = $Largeur;
					$Height = $Dimensions[1] * ($Largeur/$Dimensions[0]);
				}
			}else{
				//Cas du portrait
				$Width  = $Largeur;
				$Height  = $Dimensions[1] * ($Largeur / $Dimensions[0]);
				if ($Height<$Hauteur)
				{
					$Height = $Hauteur;
					$Width = $Dimensions[0] * ($Hauteur/$Dimensions[1]);
				}
			}
		}else{
			$Width  = $Dimensions[0];
			$Height  = $Dimensions[1];
		}
		$TempCaneva = imagecreatetruecolor($Width,$Height);
		imagecopyresampled($TempCaneva,$Img,0,0,0,0,$Width,$Height,$Dimensions[0],$Dimensions[1]);
		imagecopy($Caneva,$TempCaneva,0,0,($Width/2)-($Largeur/2),($Height/2)-($Hauteur/2),$Dimensions[0],$Dimensions[1]);
		if ($Out=="jpg"||$Out=="jpeg") $Test = imagejpeg($Caneva,$Dir.$Name,100);
		elseif ($Out=="gif") $Test = imagegif($Caneva,$Dir.$Name);
		elseif ($Out=="png") $Test = imagepng($Caneva,$Dir.$Name);
		return ($Test) ? $Dir.$Name : false;
	}
	
	function DriverSearch($Analyse,$Select,$GroupBy){
		$Adresse = $SavAdresse = fileDriver::getAddress($Analyse);
		$Recherche = $Analyse[sizeof($Analyse)-1]["Recherche"];
		if ($Recherche){
			$Adresse .= "/".$Recherche;
			if (preg_match("#([A-z\/\-0-9\@\*\.]+)\.([A-z]+)\.([A-z]+)\.([0-9]+)x([0-9]+)\.([A-z0-9]*)#",$Recherche,$out)) {
				$NomFichier = $out[1].".".$out[2];
				$Action = $out[3];
				$Out=$out[6];
				//On verifie que le fichier d'origine existe
				if (!file_exists($SavAdresse."/".$NomFichier)) return false;
				switch ($Action)
				{
					case "mini":
						$Largeur = $out[4];
						$Hauteur = $out[5];
						$Adr = fileDriver::Miniature($SavAdresse."/".$NomFichier,$SavAdresse,$NomFichier,$Largeur,$Hauteur,$Out);
						break;
					case "limit":
						$Largeur = $out[4];
						$Hauteur = $out[5];
						$Adr = fileDriver::LimitSize($SavAdresse."/".$NomFichier,$SavAdresse,$NomFichier,$Largeur,$Hauteur,$Out);
						break;
					default:
						die("Ce type de decoupe ($Action) n'existe pas.");
						break;
				}
				if (!$Adr) return false;
				$Results[0] = fileDriver::getAttributes($Adr,$Recherche,"Fichier",true);
			}elseif(file_exists($Adresse)||fileDriver::file_exists_i($Adresse)){
				$Adresse = fileDriver::getCaseSensitiveName($Adresse);
				$Results[0] = fileDriver::getAttributes($Adresse,$Recherche,$Analyse[sizeof($Analyse)-1]["Nom"],true);
			}
			else {
				return false;
			}
		}else{
			//Recherche d enfants
			if ($Analyse[sizeof($Analyse)-1]["Nom"]=="Dossier"){
				$Path=$Adresse;
				if (is_dir($Path)) {
					if ($dh = opendir($Path)) {
						while (($file = readdir($dh)) !== false) {
							if(is_dir($Path."/".$file) && $file!="." && $file!=".."){
								$Results[] = fileDriver::getAttributes($Path."/".$file,$file);
							}
						}
						closedir($dh);
					}
				}
			}else{
				$Path=$Adresse;
				if (is_dir($Path)) {
					if ($dh = opendir($Path)) {
						while (($file = readdir($dh)) !== false) {
							if(!is_dir($Path."/".$file) && $file!="." && $file!=".."){
								$Results[] = fileDriver::getAttributes($Path."/".$file,$file);
							}
						}
						closedir($dh);
					}
				}
			}
		}
		//----------------------------------------------//
		//Gestion des Historiques	 		//
		//----------------------------------------------//
		if (is_array($Results)){
			for($i=0;$i<sizeof($Results);$i++){
				$Results[$i]["ObjectType"] = $this->titre;
				for ($j=0;$j<sizeof($Analyse)-1;$j++){
					$Results[$i]["Historique"][] = Array(
						"Id" => $Analyse[$j]["Recherche"],
						"ObjectType" => $Analyse[$j]["Nom"]
					);
				}
			}
		}
		//----------------------------------------------//
		//Gestion du count
		//----------------------------------------------//
		if (preg_match("#COUNT\(\DISTINCT\((.*?)\)\)#",$Select,$Out)){
			$R[0]["COUNT(DISTINCT(".$Out[1]."))"] = sizeof($Results);
			unset($Results);
			$Results=$R;
		}
/*		echo "********************\r\n";
		print_r($Analyse);
		print_r($Results);*/
		return $Results;
	}

	function getAddress($Analyse){
		//On collecte les accés de l'utlisateur en cours.
		//On vérifie que la requete n'est pas vide
			//On verifie que la requete précise l'acces demandé 
			//Sinon on vérifi qu'il ait à la cible en acces ou utilisateur admin
				//Si oui on renvoie l'adresse complete
				//Si non => FAUX
		//Sinon on renvoie la liste des accés
		$Adresse = ".";
		foreach ($Analyse as $o=>$Rep){
			if ($o<sizeof($Analyse)-1){  //||sizeof($Analyse)==1
				$Adresse.="/".$Rep["Recherche"];
			}
		}
		return $Adresse;
	}

	function getAttributes($Adresse,$Nom,$Type=false,$getData=false){
		$Adresse = fileDriver::getCaseSensitiveName($Adresse);
		//$Tab["atime"] = @fileatime($Adresse);
		//$Tab["ctime"] = @filectime($Adresse);
		//$Tab["mtime"] = @filemtime($Adresse);
		$Tab["Size"] = @filesize($Adresse);
		$Type=(is_dir($Adresse)?"Dossier":"Fichier");
		$Tab['Id'] = $Nom;
		$Tab['Path'] = $Adresse;
		if ($Type=="Fichier"&&$getData){
			//$Tab['Contenu'] = @file_get_contents($Adresse);
		}
		if ($Type=="Fichier"){
			$Temp = explode(".",$Nom);                        
			$Tab['Type'] = $Temp[count($Temp)-1];
			$Tab['Mod'] = $Temp[0];
			$Tab['Mime'] = mime_content_type($Adresse);
		}
		$Tab['Nom'] = $Nom;
		$Tab['Url'] = $Adresse;
		$Tab['ObjectType'] = $Type;
		return $Tab;
	}

	function searchAll()
	{
		return fileDriver::getReflexiveRelatives(0,"c","");
	}

	function multiSearch($Recherche){
	}


	function getReference(){
	}


	function getReflexiveRelatives($id,$typeSearch,$Analyse){
		if (!$Analyse)
		$Path = "./";
		else $Path = fileDriver::getAddress($Analyse);
		if ($typeSearch=='p') return false;
		if (is_dir($Path)) {
			if ($dh = opendir($Path)) {
				while (($file = readdir($dh)) !== false) {
					if(is_dir($Path."/".$file) && $file!="." && $file!=".."){
						$Results[] = fileDriver::getAttributes($Path."/".$file,$file,"Dossier");
					}
				}
				closedir($dh);
			}
		}
		return $Results;
	}


	function getFkeyRelatives($id,$typeSearch,$Unused,$Unused2,$Analyse){
		$Path = fileDriver::getAddress($Analyse);
		if ($typeSearch=='p') return false;
		if (is_dir($Path)) {
			if ($dh = opendir($Path)) {
				while (($file = readdir($dh)) !== false) {
					if(is_file($Path."/".$file) && $file!="." && $file!=".."){
						$Results[] = fileDriver::getAttributes($Path."/".$file,$file,$this->titre);
					}
				}
				closedir($dh);
			}
		}
		$GLOBALS["Chrono"]->stop("RECH FICHIERS");
		return $Results;
	}

	function checkPath($Path){
		//Url si pas definie alors stockage dans le dossier utilisateur par defaut
	  if(empty($Path))
	    return "Home/".$GLOBALS["Systeme"]->User->Id."/";
		$Tab = $GLOBALS['Systeme']->Modules[$this->Module]->callData($Path);
		//Analyse,validation et creation de l emplacement de stockage
		if (!sizeof($Tab)) $createFolder = true;
		$Url = explode("/",$this->newProperties['Url']);
		for ($i=1;$i<count($Url);$i++){
			$pastUrl .= $Url[$i]."/";
			if(!file_exists($pastUrl)) mkdir($pastUrl,0777);
			$Emplacement.=$Url[$i].'/';
		}
		return $Emplacement;
	}

	function checkName($chaine){
		//On enleve les accents
		$chaine= strtr($chaine,  "ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿ#Ññ","aaaaaaaaaaaaooooooooooooeeeeeeeecciiiiiiiiuuuuuuuuynn" );
		//On remplace tous ce qui n est pas une lettre ou un chiffre par un _
		$chaine = preg_replace('/([^.a-z0-9]+)/i', '_', $chaine);
		//On ajoute le timestamp au nom de fichier
		// 		$chaine = preg_replace('#(.+)\.[a-z]{3})#i','$1-'.time().'.$2',$chaine);
		return $chaine;
	}

        function getFinalName($P,$N,$Num)
          /* P est le chemin, N le nom, Num le numéro en test */
          {
              $E = explode('.',$N);
              if ( file_exists($P.$E[0]."_".$Num.".".$E[1]) ) {
                  return fileDriver::getFinalName($P,$N,$Num+1);
              }
              else {
                  return $E[0]."_".$Num.".".$E[1];
              }
          }

                        
	function insertObject(){
		//Verification et Definition des Informations
		//Adresse de stockage
		$this->newProperties['Url'] = fileDriver::checkPath($this->newProperties['Url']);
		//Nom , on verifie que le nom est bien conforme aux specifications url
		$this->newProperties['Nom'] = fileDriver::checkName($this->newProperties['Nom']);
		//Temp , on verifie si il s agit d un fichier upload� , dans ce cas on recupere la variable $_FILE  et on injecte le contenu dans le fichier definitif
		if ($this->newProperties['Temp']!=""){
			//Donc fichier present dans le dossier temporaire
			if (empty($this->newProperties['Nom'])) {
				$this->newProperties['Nom'] = fileDriver::checkName($_FILES[$this->newProperties['Temp']]['name']);
			}
			// 				echo "EMPLACEMENT --> ".$Path.$No
			$Path = $this->newProperties['Url'];
                        $this->newProperties['Nom'] = fileDriver::getFinalName($Path,$this->newProperties['Nom'],0);
			if(!move_uploaded_file($_FILES[$this->newProperties['Temp']]['tmp_name'], $Path . $this->newProperties['Nom']) ){$BLa=true;}
		}else{
			//On cree le fichier , si impossible alors on retourne faux
			if (!$Fichier = fopen($this->newProperties['Url'].$this->newProperties['Nom'],"w+")) {
				return false;
			}
			//Gestion du contenu
			if (is_array ($this->newProperties['Contenu'])) $this->newProperties['Contenu'] = serialize ($this->newProperties['Contenu']);
			//Remplissage du fichier
			//$this->WriteFile($Fichier,$this->newProperties['Contenu'],$this->newProperties['Type']);
                        
			fwrite($Fichier,$this->newProperties['Contenu']);
			//Fermeture
			fclose($Fichier);
		}
		//On redefinie les proprietes afin de mettre l objet a jour
		$this->newProperties = fileDriver::getAttributes($this->newProperties['Url'],$this->newProperties['Nom'],"Fichier",true);
		if (!$BLa) $this->newProperties["Url"] = $this->newProperties['Url'].$this->newProperties['Nom'];
		
		return $this->newProperties;
	}


	function createData(){
	}

	function insertKey($Tab,$Type){
	}

	function WriteFile(){
		switch ($this->newProperties['Type']){
			default:
				//On cree le fichier , si impossible alors on retourne faux
				if (!$Fichier = fopen($this->newProperties['Url'].$this->newProperties['Nom'],"w+")) {
					return false;
				}
				//Gestion du contenu
				if (is_array ($this->newProperties['Contenu'])) $this->newProperties['Contenu'] = serialize ($this->newProperties['Contenu']);
				//Remplissage du fichier
				fwrite($Fichier,$this->newProperties['Contenu']);
				//Fermeture
				fclose($Fichier);
				break;
		}
	}
	function Erase($Object){
                if ( empty($Object->Url) ) return false;
		if (!file_exists($Object->Url)) return false;
		return (unlink($Object->Url)) ? true:false;
	}


	function EraseAssociation($Relative,$ObjId,$Type){
	}


	/*---------------------------------
	 |           PRIVEE               |
	 ---------------------------------*/

	/*---------------------------------
	 |           CREATION              |
	 ---------------------------------*/

	function init() {
	}

	function initAssoc() {
	}

	function saveData(){
	}


	/*---------------------------------
	 |           RECHERCHE             |
	 ---------------------------------*/


	/* Cette fonction range et classe dans un tableau les donnees trouvees.
	 Renvoi: le tableau de resultat.
	 Parametres: les donnees trouvees dans la base de donnees, la recherche effectuee*/
	function analyzeSearch($Donnees, $Recherche) {
		$Resultat= Array();
		$compteur=0;
		$totalCibles=count($this->Cibles);
		//On procede au calcul de la note que l'on enregistre, avec le reste, dans le tableau final
		while($Enregistrement=mysql_fetch_assoc($Donnees)){
			foreach ($this->Cibles as $valeurCible){
				foreach ($Enregistrement as $clefEnr=>$valeurEnr){
					$Resultat[$compteur][$clefEnr] = $valeurEnr;
					//Calcul de la note
					$note= (preg_match('!'.$Recherche.'!i', $valeurEnr) && $clefEnr== $valeurCible['nom']) ? $this->calcNote($valeurEnr,$Recherche,$valeurCible['searchorder']): 10;
				}
			}
			$Resultat[$compteur]['note'] = $note;
			$compteur++;
		}
		$Resultat = $this->bubbleSort($Resultat,'note');
		$Resultat=$this->setSearchOrder($Resultat);
		return $Resultat;
	}

	/*---------------------------------
	 |          TEST/AUTO              |
	 ---------------------------------*/

	function getTableName(){
	}

	function findReflexive(){
	}

	function getTime(){
	}


}
